package com.dangwen.proto.calculator;

import com.dangwen.proto.util.ByteUtil;

import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * Description
 *
 * @author DangWen
 */
public class CmdHandler {
    private static int sendHandleFlag = 0;
    private static final int MIN_LENGTH = 10;

    public int cmdSendHandle(String topic, short cmd, byte[] pb, int pbLength) {
        if (sendHandleFlag == 1) {
            return 1;
        }

        sendHandleFlag = 1; // 锁定处理

        ComToServerData comSendData = new ComToServerData();
        comSendData.cmd = cmd;
        System.arraycopy(pb, 0, comSendData.pbData, 0, pbLength);
        comSendData.length = pbLength + MIN_LENGTH;
        comSendData.crc = calculateCRC32(comSendData.cmd, comSendData.length - 8, 0);

        // 执行字节序转换
        comSendData.cmd = Short.reverseBytes(comSendData.cmd);
        comSendData.crc = Integer.reverseBytes(comSendData.crc);
        comSendData.length = Integer.reverseBytes(comSendData.length);

        if (topic == null) {
            userMqttPublishToServer(comSendData, pbLength + MIN_LENGTH);
        } else {
            userMqttPublish(topic, comSendData, pbLength + MIN_LENGTH);
        }

        sendHandleFlag = 0; // 解锁处理
        return 0;
    }

    private static int calculateCRC32(short cmd, int length, int init) {
        int crcValue = init;
        byte[] data = ByteBuffer.allocate(6).putShort(cmd).putInt(length).array();

        for (byte b : data) { // 遍历输入数据
            int index = (crcValue ^ b) & 0xff; // 计算CRC32表的索引
            crcValue = (CRC32Calculator.CRC32C_TABLE[index] ^ (crcValue >> 8)); // 使用CRC32表更新CRC值
        }
        return crcValue;
    }

    private static final int[] CRC32C_TABLE = {
            // CRC32查找表的值（省略了）
    };

    private void userMqttPublishToServer(ComToServerData data, int length) {
        // 发布数据到MQTT服务器的实现（省略了）
        System.out.println(data.cmd + " " + data.length + " " + data.crc);
    }

    private void userMqttPublish(String topic, ComToServerData data, int length) {
        // 发布数据到MQTT服务器的实现（省略了）
        System.out.println(topic + " " + data.cmd + " " + data.length + " " + data.crc);
    }

    public static class ComToServerData implements Serializable {
        short cmd;
        byte[] pbData = new byte[256]; // 根据实际情况设置数组大小
        int length;
        int crc;
    }

    public static void main(String[] args) {
        String hexString = "00000037bfa533ad00010a0c303038306531303433613330120f3139322e3136382e3133372e313830180020d66c28383205082910cf03";
        byte[] byteArray = new byte[hexString.length() / 2];
        for (int i = 0; i < hexString.length(); i += 2) {
            byteArray[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i+1), 16));
        }
        byte[] byteArray_data3 = Arrays.copyOfRange(byteArray, 10, byteArray.length);

        short cmd = 1;
        ComToServerData comSendData = new ComToServerData();
        comSendData.cmd = cmd;
        System.arraycopy(byteArray_data3, 0, comSendData.pbData, 0, Math.min(byteArray_data3.length, comSendData.pbData.length));
        comSendData.length = byteArray_data3.length + MIN_LENGTH;
        comSendData.crc = calculateCRC32(comSendData.cmd, comSendData.length - 8, 0);

        // 执行字节序转换
        comSendData.cmd = Short.reverseBytes(comSendData.cmd);
        comSendData.crc = Integer.reverseBytes(comSendData.crc);
        comSendData.length = Integer.reverseBytes(comSendData.length);

        byte[] bytes = ByteUtil.objectToBytes(comSendData);
        assert bytes != null;
        String s = ByteUtil.bytesToHex(bytes);
        System.out.println(s);
    }
}

